/// Author: QP
/// Version: 1.0
/// Date:2022/11
/// HCC转换FHIR工具类
Class HCC.FHIR.Transformer Extends %RegisteredObject
{

/// debug mode. If set to true, will save generated SDA into Debug path
Property Debug As %Boolean [ InitialExpression = 0 ];

/// full path to store SDA file in debug mode
Property DebugPath As %String;

/// debug file GUID name
Property FileGUID As %String [ Internal ];

/// xslt transformer
Property Transformer As HS.Util.XSLTTransformer [ Internal ];

Method %OnNew(pDebug, pDebugPath) As %Status [ Private, ServerOnly = 1 ]
{
	Set ..Debug = pDebug, ..DebugPath = pDebugPath
	Set ..Transformer= ##class(HS.Util.XSLTTransformer).%New()
	Quit $$$OK
}

/// HCC DOC TRANFTER TO SDA
/// INPUT: pHCC, SOURCE STREAM
/// INPUT: pSDA, REFERENCE OF TARGET STREAM
Method HCCToSDA(pHCC As %Stream.Object, ByRef pSDA As %Stream.Object) As %Status
{
	Set tSC = $$$OK
	Try 
	{
		If $ISOBJECT(pSDA) &&(pSDA.%IsA("%Stream.Object"))
		{			
		}
		Else
		{
			Set tSC = $$$ERROR(-10000,"Input parameter pSDA is not a stream")
			Quit
		}

		// transfter to SDA first
		Set tSlash = $Case($system.Version.GetOS(),"Windows":"\",:"/")
		Set tXSL="file:///"_$SYSTEM.Util.InstallDirectory()_"csp"_tSlash_"xslt"_tSlash_"HCC"_tSlash_"HCC2SDA.xsl"
		Set tSC = ..Transformer.Transform(pHCC,tXSL,.tSDA)
		Quit:($$$ISERR(tSC))
		D pSDA.CopyFrom(tSDA)
		
		// store SDA for debug purpose
		if (..Debug=1)
		{
			Set ..FileGUID = $Case($system.Version.GetOS(),"Windows":"\",:"/")_$SYSTEM.Util.CreateGUID()
			Set tSDAFile=##class(%Stream.FileCharacter).%New()
			Set tSC=tSDAFile.LinkToFile(..DebugPath_..FileGUID_".XML")
			Set tSDAFile.TranslateTable="UTF8"
			Do tSDAFile.Write(pSDA.Read())
			Do tSDAFile.%Save(),tSDAFile.%Close()
			Kill tSDAFile
		}
	}
	Catch ex 
	{
		Set tSC=ex.AsStatus()
	}	
	Quit tSC
}

/// SDA TRANFTER TO FHIR
/// INPUT: pSDA, SOURCE STREAM
/// INPUT: pFHIR, REFERENCE OF TARGET STREAM
Method SDAToFHIR(pSDA As %Stream.Object, ByRef pFHIR As %Stream.Object) As %Status
{
	If ($ISOBJECT(pSDA) && pSDA.%IsA("%Stream.Object"))
	{}
	Else
	{
		Quit $$$ERROR(-10000,"Input parameter pSDA is not a stream")
	}
		
	Set tSC = $$$OK
	Try 
	{
		// transfer SDA to FHIR
		Set tFHIR = ##class(HS.FHIR.DTL.Util.API.Transform.SDA3ToFHIR).TransformStream(pSDA,"HS.SDA3.Container","R4")
		If ('$ISOBJECT(tFHIR))
		{
			K tFHIR
			Set tSC = $$$ERROR(-10000,"SDA transfer to FHIR error!")
			Quit 
		}
		Else
		{
			Set:($Get(pFHIR)="") pFHIR=##class(%Stream.TmpCharacter).%New()
			
			Do pFHIR.Write(tFHIR.bundle.%ToJSON())
			Do tFHIR.%Close()
			
			// store SDA for debug purpose
			if ..Debug=1
			{
				Set tFHIRFile=##class(%Stream.FileCharacter).%New()
				Set tSC=tFHIRFile.LinkToFile(..DebugPath_..FileGUID_".JSON")
				Set tFHIRFile.TranslateTable="UTF8"
				Do pFHIR.Rewind()
				Do tFHIRFile.Write(pFHIR.Read())
				D tFHIRFile.%Save(),tFHIRFile.%Close()
				K tFHIRFile
			}
		}
	}
	Catch ex 
	{
		Set tSC=ex.AsStatus()
	}
	
	Quit tSC
}

/// HCC DOC TRANFTER TO FHIR
/// INPUT: pHCC, SOURCE STREAM
/// INPUT: pFHIR, REFERENCE OF TARGET STREAM
Method HCCToFHIR(pHCC, ByRef pFHIR) As %Status
{
	If ($ISOBJECT(pHCC) && pHCC.%IsA("%Stream.Object"))
	{}
	Else
	{
		Quit $$$ERROR(-10000,"Input parameter pHCC is not a stream")
	}

	// transfter to SDA first
	Set tSDA = ##class(%Stream.GlobalCharacter).%New()
	Set tSC = ..HCCToSDA(pHCC,.tSDA)
	Quit:($$$ISERR(tSC)) tSC

	// store SDA for debug purpose
    Set tSC = ..SDAToFHIR(tSDA,.pFHIR)
	Quit tSC
}

ClassMethod Test()
{
	Set tTarget=""
	Set t=..%New(0,"")
	Set tStream = ##class(%Stream.TmpCharacter).%New()
	Do tStream.Write(^QP1)
	Set tSC= t.HCCToFHIR(tStream,.tTarget)
	W tSC,!
	Do tTarget.Rewind()
	W tTarget.Read()
}

}
